home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / asmbler.arc / IBMSPEC.ASM < prev    next >
Assembly Source File  |  1988-11-19  |  14KB  |  383 lines

  1. ; [23-Feb-84]
  2. ; Added GETATTR routine and added attribute value to arglist of writer
  3. ; to support inverse video, blinking, etc.
  4. ; <BEEBE.IBM-PC>IBMSPEC.ASM.22, 20-Feb-84 13:52:00, Edit by BEEBE
  5. ; [20-Feb-84]
  6. ; alphabetized routines (except for SCREENHEIGHT and SCREENHEIGHT because
  7. ; of stupid assembler bug), prettyprinted code, inserted symbolic DOS/BIOS
  8. ; interrupts and function codes, added SCREENHEIGHT and CURRXY routines,
  9. ; made SCREENHEIGHT and SCREENWIDTH support standard IBM monitors as well
  10. ; as Quadram Quadscreen
  11. USE_SCROLL EQU 0
  12. TRY_INVERSE EQU 0
  13. DEBUG EQU 1
  14. assume  cs:ibmspec
  15.  
  16. public  bell, currxy, eeol, eeos, getattr, gotoxy, screenheight, screenwidth
  17. public  writer
  18.  
  19. include ascii.inc
  20. include dos.inc
  21.  
  22. ibmspec segment para public 'code'
  23.  
  24. enter   macro
  25.         push    bp              ; save old frame pointer
  26.         mov     bp,sp           ; make new frame pointer
  27.         add     bp,6            ; pointing to args on stack
  28.         endm
  29.  
  30. exit    macro
  31.         pop     bp              ; restore old frame pointer
  32.         endm
  33.  
  34. enterds macro
  35.         push    bp              ; save old frame pointer and data
  36.         push    ds              ; segment register
  37.         mov     bp,sp           ; and make new frame pointer pointing to
  38.         add     bp,8            ; args on stack
  39.         endm
  40.  
  41. exitds  macro
  42.         pop     ds              ; restore data segment register and old
  43.         pop     bp              ; frame pointer
  44.         endm
  45.  
  46. wonb    equ     7               ; video mode for white char on black background
  47.  
  48. ;=======================================================================
  49. ; Function Screenheight : word { return screen height in ax }
  50.  
  51. assume  cs:ibmspec
  52.  
  53. screenheight proc far
  54.         mov     ah,$VIDEO_GETVIDEOSTATE
  55.         int     $VIDEO          ; current mode to al
  56.         xor     bx,bx           ; clear bx
  57.         mov     ah,$QS_DESCRIBEMODE
  58.         int     $VIDEO          ; get Quadscreen status (if any)
  59.         test    bx,bx           ; bx = 0 still?
  60.         jz      stdht           ; yes, standard IBM mode
  61.         mov     al,bh           ; Quadscreen height
  62.         xor     ah,ah           ; clear top half of ax
  63.         ret
  64. stdht:
  65.         mov     ax,25           ; IBM modes 0..7 are all 25 lines
  66.         ret
  67. screenheight endp
  68.  
  69. ;=======================================================================
  70. ; Function Screenwidth : word { return screen width in ax }
  71.  
  72. assume  cs:ibmspec,ds:ibmspec
  73.  
  74. screenwidth proc far
  75.         mov     ah,$VIDEO_GETVIDEOSTATE
  76.         int     $VIDEO          ; current mode to al
  77.         xor     bx,bx           ; clear bx
  78.         mov     ah,$QS_DESCRIBEMODE
  79.         int     $VIDEO          ; get Quadscreen status (if any)
  80.         test    bx,bx           ; bx = 0 still?
  81.         jz      stdwd           ; yes, standard IBM mode
  82.         mov     al,bl           ; Quadscreen width
  83.         xor     ah,ah           ; clear top half of ax
  84.         ret                     ; return to caller
  85. stdwd:
  86.         mov     bl,al           ; mode
  87.         and     bx,7            ; clear all but 3 lower bits
  88.         sal     bl,1            ; 2*mode for table word index
  89.         push    ds              ; save ds
  90.         push    cs
  91.         pop     ds              ; make ds = cs
  92.         mov     ax,wtable[bx]   ; screen width according to mode
  93.         pop     ds              ; restore ds
  94.         ret                     ; return to caller
  95.  
  96. wtable: dw      40              ; mode = 0
  97.         dw      40              ; 1
  98.         dw      80              ; 2
  99.         dw      80              ; 3
  100.         dw      80              ; 4
  101.         dw      80              ; 5
  102.         dw      80              ; 6
  103.         dw      80              ; 7
  104.  
  105. screenwidth endp
  106.  
  107. ;=======================================================================
  108. ; Procedure Bell { ring the bell }
  109.  
  110. assume  cs:ibmspec
  111. kb_ctl  equ     61h             ; speaker I/O address
  112.  
  113. bell    proc    far
  114.         in      al,kb_ctl
  115.         push    ax              ; save current port contents
  116.         mov     bx,0c0h         ; outer loop delay count
  117. b65:
  118.         and     al,0fch
  119.         out     kb_ctl,al
  120.         mov     cx,48h          ; delay loop count
  121. b66:
  122.         loop    b66             ; do the delay
  123.         or      al,2
  124.         out     kb_ctl,al
  125.         mov     cx,48h          ; delay loop count
  126. b67:
  127.         loop    b67             ; do the delay
  128.         dec     bx              ; outer loop done?
  129.         jnz     b65             ; loop back if not
  130.         pop     ax              ; recall original port contents
  131.         out     kb_ctl,al       ; and restore them
  132.         ret                     ; return to caller
  133. bell    endp
  134.  
  135. ;=======================================================================
  136. ; Procedure Currxy (column,row : word); { return current cursor position }
  137.  
  138. assume  cs:ibmspec
  139.  
  140. currxy  proc    far
  141.         enter
  142.         mov     ah,$VIDEO_GETVIDEOSTATE
  143.         int     $VIDEO          ; get current mode, width, page
  144.         mov     ah,$VIDEO_GETCURSORPOSITION
  145.         int     $VIDEO          ; get (row,column) in (dh,dl)
  146.         xor     ah,ah           ; clear top half of ax
  147.         mov     al,dl           ; column
  148.         mov     [bp+2],ax       ; store column
  149.         mov     al,dh           ; row
  150.         mov     [bp],ax         ; store row
  151.         exit
  152.         ret     4               ; return discarding stack arguments
  153. currxy  endp
  154.  
  155.  
  156. ;=======================================================================
  157. ; Procedure Eeol { erase from cursor to end of line }
  158.  
  159. assume  cs:ibmspec
  160.         db      "<<EEOL>>"
  161. eeol    proc    far
  162.         call    screenwidth
  163.         mov     si,ax           ; save screen width
  164.         mov     ah,$VIDEO_GETCURSORPOSITION
  165.         int     $VIDEO          ; get cursor (row,column) in (dh,dl)
  166.         xor     dh,dh           ; clear row
  167.         sub     si,dx           ; length of remainder of screen line
  168.         jle     e1              ; exit if nothing to clear
  169.         mov     cx,si           ; count
  170.         mov     al,' '          ; blank for clearing
  171.         mov     bl,wonb         ; video attribute
  172.         mov     ah,$VIDEO_SETATTRCHAR
  173.         int     $VIDEO          ; erase the rest of the line
  174. e1:
  175.         ret                     ; return to caller
  176. eeol    endp
  177.  
  178. ;=======================================================================
  179. ; Procedure Eeos { erase from cursor to end of screen }
  180.  
  181. assume  cs:ibmspec
  182.  
  183.         db      "<<EEOS>>"
  184. eeos    proc    far
  185.         enter
  186.         call    screenwidth
  187.         mov     si,ax           ; save screen width
  188.         call    screenheight
  189.         mov     di,ax           ; save screen height
  190.         mov     ah,$VIDEO_GETVIDEOSTATE
  191.         int     $VIDEO          ; get current mode, width, and page (in bh)
  192.         mov     ah,$VIDEO_GETCURSORPOSITION
  193.         int     $VIDEO          ; get (row,column) in (dh,dl)
  194. IF USE_SCROLL
  195.         test    dx,dx           ; at (0,0)?
  196.         jnz     sloweeos        ; no
  197.         mov     ax,di           ; height
  198.         dec     al              ; height-1
  199.         mov     dh,al           ; height-1
  200.         mov     ax,si           ; width
  201.         dec     al              ; width-1
  202.         mov     dl,al           ; (height-1,width-1) in (dh,dl) = lower right
  203.         xor     cx,cx           ; set upper left corner of scroll = (0,0)
  204.         xor     al,al           ; al = 0 means blank entire page
  205.         mov     ah,$VIDEO_SCROLLUP
  206.         int     $VIDEO          ; do fast screen clear
  207.         jmp     eeosdone
  208. ENDIF
  209. sloweeos:                       ; slow erase of partial screen
  210.         mov     ax,di           ; screen height
  211.         mov     cx,si           ; screen width
  212.         mul     cl              ; (height)*(width) = screen size in cx
  213.         mov     di,ax           ; save screen size
  214.         mov     ax,si           ; screen width
  215.         mul     dh              ; (row)*(width) = count from bol to eos
  216.         xor     dh,dh           ; column in dx
  217.         sub     di,ax           ; (screen chars) - (count from bol to eos)
  218.         sub     di,dx           ; - column =
  219.         mov     cx,di           ; count of chars to blank
  220.         mov     al,' '
  221.         mov     bl,wonb         ; video mode
  222.         mov     ah,$VIDEO_SETATTRCHAR
  223.         int     $VIDEO          ; blank rest of screen
  224. eeosdone:
  225.         exit
  226.         ret
  227. eeos    endp
  228.  
  229. ;=======================================================================
  230. ; Function Getattr : word { Return video attr of character at cursor }
  231. ;
  232. assume  cs:ibmspec
  233.         db      "<<GETATTR>>"
  234.  
  235. getattr proc    far
  236.         mov     ah,$VIDEO_GETVIDEOSTATE
  237.         int     $VIDEO          ; get current mode, width, and page
  238.         mov     ah,$VIDEO_GETATTRCHAR
  239.         int     $VIDEO
  240.         mov     al,ah           ; attribute in al
  241.         xor     ah,ah           ; clear top of ax (function result)
  242.         ret                     ; return to caller
  243. getattr endp
  244.  
  245.  
  246. ;=======================================================================
  247. ; Procedure Gotoxy (column,row : word) { Move cursor to (column,row) }
  248.  
  249. assume  cs:ibmspec
  250.         db      "<<GOTOXY>>"
  251.  
  252. gotoxy  proc    far
  253.         enter
  254.         mov     ah,$VIDEO_GETVIDEOSTATE
  255.         int     $VIDEO          ; get current mode, width, and page
  256.         mov     dl,[bp+2]       ; column
  257.         mov     dh,[bp]         ; row
  258.         xor     bh,bh           ; current page = 0
  259.         mov     ah,$VIDEO_SETCURSORPOSITION
  260.         int     $VIDEO
  261.         exit
  262.         ret     4               ; return discarding stack arguments
  263. gotoxy  endp
  264.  
  265. ;=======================================================================
  266. ; Procedure Writer (attr: word; thestr: adsmem; count: integer);
  267. ; { Write 'count' characters of 'thestr' at the current cursor position
  268. ;   using video attribute attr (e.g. obtained by Getattr).
  269. ;   Characters beyond the end-of-screen-line are not displayed. }
  270. ;
  271. ; Stack looks like
  272. ;   0 - count
  273. ;   2 - address of thestr
  274. ;   4 - segment of thestr
  275. ;   6 - attr
  276.  
  277. assume  cs:ibmspec
  278.  
  279. ;
  280. ; IBM monitor attribute byte bit assignments
  281. ; -------------------------------------
  282. ; | blink | R | G | B | I | R | G | B |
  283. ; -------------------------------------
  284. ;        -----   -----
  285. ;        back    fore 
  286. ;
  287. blink   equ     80h
  288. intensity equ   08h
  289. forergb equ     70h
  290. backrgb equ     07h
  291.  
  292.         db      "<<WRITER>>"
  293. writer  proc    far
  294.         enterds
  295.         mov     di,[bp]         ; grab the count
  296.         test    di,di           ; count > 0 ?
  297.         jle     writerdone      ; exit if nothing to write
  298.         mov     si,[bp+2]       ; grab the address of the characters to write
  299.         mov     ds,[bp+4]       ; grab the segment of thestr
  300.  
  301.         call    screenwidth
  302.         push    ax              ; save screen width
  303.         mov     ah,$VIDEO_GETCURSORPOSITION
  304.         int     $VIDEO
  305.         pop     ax              ; recall screen width
  306.         dec     ax              ; al = width of screen, dl = cursor column
  307.         mov     bl,al           ; save maximum displayable column in bl
  308.         sub     al,dl           ; maximum number of chars to write
  309.         jle     writerdone      ; exit if nothing to write
  310.         xor     ah,ah           ; clear top of ax
  311.         cmp     di,ax           ; user-specified count > remaining line length?
  312.         jle     writ2           ; no
  313.         mov     di,ax           ; yes, truncate the line
  314. writ2:
  315.         cld                     ; clear direction flag to increment si
  316.         mov     ah,$VIDEO_GETVIDEOSTATE
  317.         int     $VIDEO          ; get current page in (bh)
  318.         mov     ah,$VIDEO_GETCURSORPOSITION
  319.         int     $VIDEO          ; get (row,column) in (dh,dl)
  320.         push    dx              ; save it - later accessed by [bp-10]
  321.  
  322. writlp:
  323.         lodsb                   ; get next byte into al and increment si
  324.         mov     cx,1            ; repeat count = 1
  325.         cmp     al,.HT          ; tab?
  326.         jne     writ3           ; no
  327.         mov     cl,[bp-10]      ; yes, get current cursor column (0,1,2,...)
  328.         and     cl,7            ; cl MOD 8
  329.         neg     cl              ; -(cl MOD 8)
  330.         add     cl,8            ; 8 - (cl MOD 8) = columns of blank fill
  331.         mov     al,' '          ; change tab to blank
  332.  
  333. writ3:
  334.         mov     dl,[bp-10]      ; current column
  335.         add     dl,cl           ; new column
  336.         cmp     bl,dl           ; maximum column < new current column?
  337.         jl      writerdone      ; yes, no more room in current line
  338.         mov     [bp-10],dl      ; update cursor column
  339. if DEBUG
  340.         mov     bl,7
  341. else
  342.         mov     bl,[bp+6]       ; get attribute byte
  343. endif
  344. if TRY_INVERSE
  345. ;
  346. ; display the character in the inverse of the current mode
  347. ; [experiment]
  348. ;
  349.  
  350.         mov     ah,$VIDEO_GETATTRCHAR
  351.         int     $VIDEO          ; get (attribute,char) in (ah,al) for page (bh)
  352.         push    cx              ; save count
  353.         mov     bl,ah           ; mode byte
  354.         and     bl,blink+intensity ; keep blink and intensity bits
  355.         and     ah,NOT (blink OR intensity) ; remove blink and intensity
  356.         mov     ch,ah
  357.         mov     cl,4            ; shift count
  358.         shr     ch,cl           ; move foreground into background,
  359.         shl     ah,cl           ; background into foreground,
  360.         or      ah,ch           ; merge them,
  361.         or      ah,bl           ; restore blink and intensity for new mode,
  362.         pop     cx              ; restore count
  363.         mov     bl,ah           ; and setup new mode.
  364. endif
  365.  
  366. writ4:
  367.         mov     ah,$VIDEO_SETATTRCHAR
  368.         int     $VIDEO          ; write char and attribute
  369.         mov     dl,[bp-10]      ; get current cursor column
  370.         mov     ah,$VIDEO_SETCURSORPOSITION
  371.         int     $VIDEO          ; move cursor
  372.         dec     di              ; are we done?
  373.         jnz     writlp          ; loop for more if not
  374.         pop     dx              ; restore saved dx
  375.  
  376. writerdone:
  377.         exitds                  ; restore stack at entry
  378.         ret     8               ; return discarding arguments on stack
  379. writer  endp
  380.  
  381. ibmspec ends
  382.         end
  383.